class Node:
    def __init__(self, data=None):
        self.data = data
        self.next = None
        self.prev = None


class FIFO:
    def __init__(self,max):
        self.head = Node()
        self.tail = Node()
        self.head.next = self.tail
        self.tail.prev=self.head
        self.max=max
        self.length = 0

    def on_shift(self, data):#放进去
        # a=self.full()
        # if a is None and self.length<self.max:
        assert not self.full()
        tmpPtr = self.tail
        tmpPtr_prve=self.tail.prev
        newNode = Node()
        newNode.data = data

        tmpPtr.prev = newNode
        newNode.next = tmpPtr

        tmpPtr_prve.next=newNode
        newNode.prev = tmpPtr_prve
        

        self.length += 1
    def off_shift(self):#拿出去
        # a=self.empty()
        # if a is not None and self.length<=self.max:
        assert not self.empty()
        tmpPtr=self.head.next

        self.head.next=tmpPtr.next
        tmpPtr.next.prev=self.head
        self.length-=1
        return tmpPtr.data

    def __iter__(self):
        node = self.head.next
        while node != self.tail:
            yield node.data
            node = node.next

    def full(self):
        # if self.head.next == self.tail and self.tail.prev == self.head and self.head.data!=None:
        #     return 'line is full'
        return self.length==self.max
    def empty(self):
        # if self.head.next == self.tail and self.tail.prev == self.head and self.head.data==None:
        #     return 'line is empty'
        return self.length==0


if __name__ == "__main__":
    l = FIFO(10)

    for i in range(0, 10):
        l.on_shift(i)
    for i in l:
        print(i)
    try:
        l.on_shift(100)
    except Exception:
        print("The FIFO is full")
        data = l.off_shift()
        print("The first data is: %d" % (data))
        l.on_shift(100)
        print("Access every element.")
        for i in l:
            print(i)
